package com.mtcarpenter.lambda;

import org.junit.Test;

import java.util.*;
import java.util.function.Consumer;

/**
 * @Author: mtcarpenter
 * @describe lambda 表达式语法
 * @Date: 2019/10/6
 * @Version 1.0
 */
public class Lambda01Test {

    /**
     * 1.没有参数 ,没有返回值
     */
    @Test
    public void test01() {
        System.out.println("********* jdk 1.7 **********");
        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("lambda 学习");
            }
        };
        r1.run();
        System.out.println("********* jdk 1.8 **********");
        Runnable r2 = () -> System.out.println("lambda 学习");
        r2.run();
    }

    /**
     * 2.类型声明，因为可由编译器推断得出 ，成为“类型推断”
     */
    @Test
    public void test02() {
        System.out.println("************ 类型推断 *************");
        Consumer<String> con = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };


        //  Consumer  类型 决定 new Consumer 类型
       /*
       Consumer<String> con = new Consumer<Integer>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        con.accept("传递参数!");
        */

        // accept 方法中类型 由 new Consumer 决定
      /* new Consumer<String>() {
            @Override
            public void accept(Integer s) {
                System.out.println(s);
            }
        }
        */

        System.out.println("************ lambda *************");
        Consumer<String> con1 = (String s) -> {
            System.out.println(s);
        };
        con1.accept("传递参数！");

        Consumer<String> con2 = (s) -> {
            System.out.println(s);
        };
        con2.accept("传递参数！");
    }

    /**
     * 数组、集合类型推断
     */
    @Test
    public void test03() {
        int[] arr1 = new int[]{1, 2, 3};
        // 数组类型自动推断
        int[] arr2 = {1, 2, 3};

        // 集合类型自动推断 不用明确声明泛型类型，编译器就可以自己推断出来。
        List<String> list1 = new ArrayList<String>();
        List<String> list2 = new ArrayList<>();

        HashMap<String, String> hashMap1 = new HashMap<String, String>();
        HashMap<String, String> hashMap2 = new HashMap<>();
    }

    /**
     * 3.一个参数，一条语句，其都可以省略
     */
    @Test
    public void test04() {
        System.out.println("*************************");
        // 复制 test02 最后中类型推断语句
        Consumer<String> con1 = (s) -> {
            System.out.println(s);
        };
        con1.accept("传递参数！");

        System.out.println("*************************");
        // (s) 形参中只有一个参数，() 括号直接省略不写
        Consumer<String> con2 = s -> {
            System.out.println(s);
        };
        con2.accept("传递参数！");
        System.out.println("*************************");
        //  函数体只有一条语句也可以省略，{ System.out.println(s);} --->System.out.println(s)
        Consumer<String> con3 = s -> System.out.println(s);
        con3.accept("传递参数！");
    }

    /**
     * 4.两个或以上的参数，多条执行语句，并且可以有返回值
     */
    @Test
    public void test05() {
        System.out.println("********** jdk 1.7 *************");
        List<Integer> list = Arrays.asList(15, 5, 35, 25, 45);
        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1, o2);
            }
        });
        System.out.println("list = " + list);

        System.out.println("********** jdk 1.8 *************");
        List<Integer> list1 = Arrays.asList(15, 5, 35, 25, 45);
        // { return  o1-o2;} 函数体中只包含一条语句的时候 {} 花括号和 return 都可以省略
        // Collections.sort(list1,(o1, o2) -> { return  o1-o2;});
        Collections.sort(list1, (o1, o2) -> o1 - o2);
        System.out.println("list1 = " + list1);
    }

    /**
     * 5.表达式语法整合
     */
    @Test
    public void test06() {
        System.out.println("********** jdk 1.8 lambda 表达式语法整合 *************");
        // 类型声名 (String o1)
        Consumer<String> con1 = (String o1) -> {
            System.out.println(o1);
        };
        con1.accept("类型声名 (String o1)");
        // 不使用类型 (String o1) 》 ( o1 )
        Consumer<String> con2 = (o1) -> {
            System.out.println(o1);
        };
        con2.accept("不使用类型 (String o1) 》 ( o1 )");
        // 一个参数 可以取消 形式参数的括号  ( o1 ) 》 o1
        Consumer<String> con3 = o1 -> {
            System.out.println(o1);
        };
        con3.accept("一个参数 可以取消 形式参数的括号  ( o1 ) 》 o1");
        // 没有参数 不能省略形式参数的括号 ()
        Runnable r1 = () -> {
            System.out.println("没有参数 不能省略形式参数的括号");
        };
        // 函数体只有一条语句可以取消花括号 {}, { System.out.println(o1); } 》  System.out.println(o1)
        Consumer<String> con4 = o1 -> System.out.println(o1);
        con4.accept("函数体只有一条语句可以取消花括号 {}, { System.out.println(o1); } 》  System.out.println(o1)");
        // 多个参数 一条语句 形式参数的括号（） 不能省略
        Comparator<Integer> com1 = (o1, o2) -> {
            return o1.compareTo(o2);
        };
        System.out.println("o1  o2 比较大小 "+com1.compare(10, 20));
        // 多个参数 一条语句 可以省略 {} 和 return， {   return o1.compareTo(o2); } 》 o1.compareTo(o2)
        Comparator<Integer> com2 = (o1, o2) -> o1.compareTo(o2);
        System.out.println("o1  o2 比较大小 "+com2.compare(10, 20));
        // 多个参数 多条语句 括号（）和花括号 {} 都不能省略
        Comparator<Integer> com3 = (o1, o2) -> {
            System.out.println("o1 = "+o1 + "  o2 = "+o2);
            return o1.compareTo(o2);
        };
        System.out.println("o1  o2 比较大小 "+com3.compare(10,20));
    }

}
